package com.gitee.melin.bee.core.service;

import java.io.Serializable;
import java.util.List;

import com.gitee.melin.bee.core.support.Pagination;
import com.gitee.melin.bee.core.support.PaginationRequest;
import com.gitee.melin.bee.model.IEntity;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.engine.jdbc.LobCreator;

/**
 *
 * @author admin@gmail.com
 */
public interface BaseService<T extends IEntity, ID extends Serializable> {

	public T getEntity(ID id);

	public ID insertEntity(T entity);

	public void updateEntity(T entity);

	public T deleteEntity(ID id);

    public void deleteEntity(T entity);

	public void deleteEntity(String key, Object value);

	public void deleteEntity(String key1, Object value1, String key2, Object value2);

	public void deleteEntity(String key1, Object value1, String key2, Object value2, String key3, Object value3);

	public List<T> findAllEntity();

	public T logicDeleteEntity(ID id);

	public void bulkDeleteEntity(ID[] ids);

	public List<T> loadEntities();

	public List<T> findByNamedParam(String propertyName, Object value);

    public List<T> findByNamedParam(Projection projection, String propertyName, Object value);

    public List<T> findByNamedParam(String[] columns, String propertyName, Object value);

    public List<T> findByNamedParam(String propertyName1, Object value1, String propertyName2, Object value2);

    public List<T> findByNamedParam(String propertyName1, Object value1, String propertyName2, Object value2,
                                    String propertyName3, Object value3);

    public List<T> findByNamedParam(String[] propertyNames, Object[] values);

	public List<T> findByNamedParam(Projection projection, String[] propertyNames, Object[] values);

    public List<T> findByNamedParam(String[] columns, String[] propertyNames, Object[] values);

	public List<T> findByNamedParam(List<String> propertyNames, List<Object> values);

	public List<T> findByNamedParamAndOrder(String propertyName, Object value, Order order);

	public List<T> findByNamedParamAndOrder(String[] propertyNames, Object[] values, Order ... orders);

    public List<T> findByNamedParamAndOrder(Projection projection, String[] propertyNames, Object[] values, Order ... orders);

    public List<T> findByNamedParamAndOrder(String[] columns, String[] propertyNames, Object[] values, Order ... orders);

	public List<T> findByNamedParamAndOrder(List<String> propertyNames, List<Object> values, Order ... orders);

	public List<T> findByNamedParamAndOrder(String joinEntity, String propertyName, Object value, Order order);

	public List<T> findByNamedParamAndOrder(String[] joinEntitys, String propertyName, Object value, Order order);

	public List<T> findByNamedParamAndOrder(String[] joinEntitys, String[] propertyNames, Object[] values, Order order);

	public Pagination<T> findByNamedParamAndOrder(String propertyName, Object value, Order order, int page, int limit);

	public Pagination<T> findPage(int page, int limit);

	public Pagination<T> findPageAndOrder(Order[] orders, int page, int limit);

	public Pagination<T> findPage(PaginationRequest<T> paginationRequest);

	public Pagination<T> findPageByNamedParam(String joinEntity, String propertyName, Object value,
                                              final int page, final int limit);

	public Pagination<T> findPageByNamedParam(String propertyName, Object value, final int page, final int limit);

    public Pagination<T> findPageByNamedParam(String propertyName1, Object value1, String propertyName2, Object value2,
                                              final int page, final int limit);

	public Pagination<T> findPageByNamedParamAndOrder(String propertyName, Object value, Order order, final int page, final int limit);

    public Pagination<T> findPageByNamedParamAndOrder(String propertyName1, Object value1, String propertyName2, Object value2,
                                                      Order order, final int page, final int limit);

	public Pagination<T> findPageByNamedParam(String[] propertyNames, Object[] values, final int page, final int limit);

    public Pagination<T> findPageByNamedParam(Projection projection, String[] propertyNames, Object[] values, final int page, final int limit);

    public Pagination<T> findPageByNamedParam(String[] columns, String[] propertyNames, Object[] values, final int page, final int limit);

	public Pagination<T> findPageByNamedParam(List<String> propertyNames, List<Object> values, final int page, final int limit);

	public Pagination<T> findPageByNamedParamAndOrder(String[] propertyNames, Object[] values, Order[] orders,
                                                      final int page, final int limit);

    public Pagination<T> findPageByNamedParamAndOrder(Projection projection, String[] propertyNames, Object[] values, Order[] orders,
                                                      final int page, final int limit);

    public Pagination<T> findPageByNamedParamAndOrder(String[] columns, String[] propertyNames, Object[] values, Order[] orders,
                                                      final int page, final int limit);

	public Pagination<T> findPageByNamedParamAndOrder(List<String> propertyNames, List<Object> values, List<Order> orders,
                                                      final int page, final int limit);

	public List<T> findByNamedParam(String[] propertyNames, Object[] values, final int offset, final int limit);

	public List<T> findByNamedParamAndOrder(String[] propertyNames, Object[] values,
                                            Order[] orders, final int offset, final int limit);

	public Long queryCount();

	public Long queryCount(String propertyName, Object value);

    public Long queryCount(String propertyName1, Object value1, String propertyName2, Object value2);

    public Long queryCount(String propertyName1, Object value1, String propertyName2, Object value2,
                           String propertyName3, Object value3);

	public Long queryCount(String[] propertyNames, Object[] values);

	public Integer deleteOrUpdateByHQL(String hql, String paramName, Object value);

	public Integer deleteOrUpdateByHQL(String hql, String propertyName1, Object value1, String propertyName2, Object value2);

	public Integer deleteOrUpdateByHQL(String hql, String[] paramNames, Object[] values);

	public LobCreator getLobCreator();

    public T queryByNamedParam(String propertyName, Object value);

    public T queryByNamedParam(String propertyName1, Object value1, String propertyName2, Object value2);

    public T queryByNamedParam(String propertyName1, Object value1, String propertyName2, Object value2,
                               String propertyName3, Object value3);

    public T queryByNamedParam(String[] propertyNames, Object[] values);

    public T queryByCriterions(Criterion... criterions);

    public <R> R queryByCriterions(Projection projection, Criterion... criterions);

    public List<T> findByCriterions(Criterion... criterions);

    public <R> List<R> findByCriterion(Projection projection, Criterion... criterions);

    public List<T> findByCriterions(Order order, Criterion... criterions);

    public <R> List<R> findByCriterion(Projection projection, Order order, Criterion... criterions);
}
